package ufmg.aprendizado;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Scanner;

import ufmg.aprendizado.classificador.Classificador;
import ufmg.aprendizado.classificador.Conjunto;
import ufmg.aprendizado.ga.Fitness;
import ufmg.aprendizado.ga.GeneticAlgorithm;
import ufmg.arcabouco.ga.IndividuoGA;

public class Main {

	public static Random rand;

	private static List<Classificador> readInput(List<String> arquivos) {
		Scanner input = null;
		List<Classificador> classificadores = new ArrayList<Classificador>();

		int id = 1;
		for (String arquivo : arquivos) {
			Classificador classificador = new Classificador(id);
			try {
				input = new Scanner(new File(arquivo));
				while (input.hasNextLine()) {
					String line = input.nextLine();
					classificador.parseLine(line);
				}
				classificadores.add(classificador);
				id++;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				input.close();
			}
		}
		return classificadores;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		int seed = 100;

		GeneticAlgorithm ga = new GeneticAlgorithm(seed);
		ga.elitismo = true;

		rand = ga.getRandom();

		System.out.println("Conjunto 2");

		// melhores parametros
		ga.geracoes = 500;
		ga.tamanhoPopulacao = 250;

		ga.cruzamento = 0.5;
		ga.mutacao = 0.0;

		ga.torneio = 100;

		List<String> files = new ArrayList<String>();
		files.add("C1.txt");
		files.add("C2.txt");
		files.add("C3.txt");

		Conjunto conjunto = new Conjunto(readInput(files));

		for (int i = 0; i < 30; i++) {
			List<Integer> teste = new ArrayList<Integer>();
			List<Integer> Dtreino = new ArrayList<Integer>();

			for (int a = 1; a <= conjunto.getInstanciaSize(); a++) {
				if (rand.nextInt(2) >= 1) {
					Dtreino.add(a);
				} else {
					teste.add(a);
				}
			}

			List<IndividuoGA> populacaoFinal = null;
			IndividuoGA best = null;
			IndividuoGA worst = null;
			double max = 0;
			double min = 101;

			ga.melhor = 0;
			ga.pior = 0;
			for (int j = 0; j < 10; j++) {

				List<IndividuoGA> populacao = ga.criarIndividuos();

				ga.init(conjunto, populacao, Dtreino);

				// System.out.println("best: "+populacao.get(0).getAcuracia());
				if (populacao.get(0).getFitness() > max) {
					max = populacao.get(0).getFitness();
					best = populacao.get(0);
				}
				if (populacao.get(populacao.size() - 1).getFitness() < min) {
					worst = populacao.get(populacao.size() - 1);
					min = worst.getFitness();
				}

				populacaoFinal = populacao;
			}

			for (IndividuoGA ind : populacaoFinal) {
				Fitness.calcular(conjunto, ind, teste);
			}
			Collections.sort(populacaoFinal);

			Fitness.calcular(conjunto, best, teste);
			Fitness.calcular(conjunto, worst, teste);

			double media = 0;
			for (IndividuoGA ind : populacaoFinal) {
				media += ind.getFitness();
			}
			media /= populacaoFinal.size();

			System.out.println(best.getFitness() + "," + worst.getFitness()
					+ "," + media + "," + calcularRepetido(populacaoFinal)
					+ "," + ga.melhor / 10 + "," + ga.pior / 10);
		}

	}

	public static int calcularRepetido(List<IndividuoGA> populacao) {
		int count = 0;

		for (int i = 0; i < populacao.size(); i++) {
			for (int j = 0; j < populacao.size(); j++) {
				if (i != j) {

					if (populacao.get(i).equals(populacao.get(j))) {
						count++;
					}
				}
			}
		}
		return count;
	}

}
